package com.example.eshop_ssm.interceptor;

import com.example.eshop_ssm.annotation.CheckLogin;
import com.example.eshop_ssm.controller.LoginAndOutController;
import com.example.eshop_ssm.entity.TbAdminUserInfo;
import com.example.eshop_ssm.service.LoginAndOutService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 登录状态的拦截器
 * 只拦截被SpringMVC控制范围内的地址
 */
public class MyInterceptor implements HandlerInterceptor {

    @Autowired
    private LoginAndOutService loginAndOutService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        //Object o  ->  这个参数就是当前被拦截的Handler方法对象（运行时类型是HandlerMethod类）
        //System.out.println("调用Handler方法前....");

        //检测o对象的运行时类型实际是不是HandlerMethod类型（可以保证类型安全），可以防止ClassCastException异常
        if(!(o instanceof HandlerMethod)){///如果不是这个HandlerMethod类型
            return true;
        }

        ////判断当前被拦截的Handler方法对象是否有@CheckLogin注解////
        HandlerMethod handlerMethod = (HandlerMethod) o;     ///在做强制转换时，容易引发ClassCastException异常
        Method method = handlerMethod.getMethod();
        //判断该method对象是否有@CheckLogin注解标记
        boolean hasCheckLogin = method.isAnnotationPresent(CheckLogin.class);
        if (hasCheckLogin){

            //从session中取出“loginUser”，判断是否为null
            //为null则代表未登录，就跳回登录页面
            //不为null则代表已登录，就放行
            TbAdminUserInfo tbAdminUser = (TbAdminUserInfo) request.getSession().getAttribute(LoginAndOutController.ADMINUSER);
            if (tbAdminUser == null) {//未登录
                //判断cookie中有没有存储“admin_user_id”（如果有代表已登录，如果没有代表未登录）
                //在请求后端时会自动携带cookie
                Cookie[] receiveCookieArray = request.getCookies();
                String admin_user_id = null;
                if (receiveCookieArray != null) {
                    for (Cookie cookie : receiveCookieArray) {
                        //cookie.getName()  -> 获取cookie的名字
                        //cookie.getValue() -> 获取cookie的值
                        if (cookie.getName().equals("adminUserId")){
                            admin_user_id = cookie.getValue();
                            break;
                        }
                    }
                }

                if (admin_user_id == null) {//cookie中没有找到“admin_user_id”  -> 未登录
                    //记录登录状态拦截前的路径，以便于登录成功之后取出该路径用于跳转对应的地址
                    request.getSession().setAttribute("forwardURL",request.getRequestURI());

                    //跳回登录页面
                    response.sendRedirect(request.getContextPath()+"/LoginAndOutController/reforwd");//打回给浏览器，让浏览器重新请求这个reforwd接口
                    //request.getRequestDispatcher("reforwd").forward(request,response);
                    return false;
                }else{//cookie中找到了“admin_user_id”  -> 已登录
                    //通过id查询到管理员用户信息对象，再存入session
                    TbAdminUserInfo adminUserInfo = loginAndOutService.selectById(Integer.parseInt(admin_user_id));
                    request.getSession().setAttribute(LoginAndOutController.ADMINUSER,adminUserInfo);
                    return true;
                }

            }else{//已登录
                //放行
                //filterChain.doFilter(request,response);
                return true;
            }

        }else{//不需要拦截登录状态验证的地址
            //放行
            //filterChain.doFilter(request,response);
            return true;
        }


        //return false  代表不放行
        //return true   代表放行

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//        System.out.println("调用Handler方法时....");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//        System.out.println("调用Handler方法后....");
    }
}
